package indigo.ueditor;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.google.common.collect.Maps;

public class PathPatternResolver {
	private static final String TIME = "time";
	private static final String FULL_YEAR = "yyyy";
	private static final String YEAR = "yy";
	private static final String MONTH = "mm";
	private static final String DAY = "dd";
	private static final String HOUR = "hh";
	private static final String MINUTE = "ii";
	private static final String SECOND = "ss";
	private static final String RAND_PREFIX = "rand:";

	private static final Pattern TOKEN_PATTERN = Pattern.compile("\\{([^\\}]+)\\}", Pattern.CASE_INSENSITIVE);

	private final Map<String, String> variables = Maps.newHashMap();

	public void putVariable(String name, String value) {
		variables.put(name, value);
	}

	public void putVariables(Map<String, String> variables) {
		variables.putAll(variables);
	}

	public String resolve(String pattern) {
		Date now = new Date();
		Matcher matcher = TOKEN_PATTERN.matcher(pattern);
		StringBuffer path = new StringBuffer();
		while (matcher.find()) {
			String token = matcher.group(1);
			String lowerToken = token.toLowerCase();
			String replacement;
			if (lowerToken.equals(TIME)) {
				replacement = String.valueOf(System.currentTimeMillis());
			} else if (lowerToken.equals(FULL_YEAR)) {
				replacement = formatDate("yyyy", now);
			} else if (lowerToken.equals(YEAR)) {
				replacement = formatDate("yy", now);
			} else if (lowerToken.equals(MONTH)) {
				replacement = formatDate("MM", now);
			} else if (lowerToken.equals(DAY)) {
				replacement = formatDate("dd", now);
			} else if (lowerToken.equals(HOUR)) {
				replacement = formatDate("HH", now);
			} else if (lowerToken.equals(MINUTE)) {
				replacement = formatDate("mm", now);
			} else if (lowerToken.equals(SECOND)) {
				replacement = formatDate("ss", now);
			} else if (lowerToken.startsWith(RAND_PREFIX)) {
				int length = Math.min(Integer.parseInt(lowerToken.substring(RAND_PREFIX.length())), 12);
				replacement = String.format("%.12f", Math.random()).substring(2, 2 + length);
			} else if (variables.containsKey(token)) {
				replacement = variables.get(token);
			} else {
				replacement = token;
			}
			matcher.appendReplacement(path, replacement);
		}
		matcher.appendTail(path);
		return path.toString();
	}

	private static String formatDate(String pattern, Date date) {
		return new SimpleDateFormat(pattern).format(date);
	}
}
